Skip to content

fix(web): make Supervisor actions report their outcome and pin the chat recipient - #827

Merged
unohee merged 1 commit into
mainfrom
claude/dashboard-harden
Oct 19, 2026
Merged

unohee merged 1 commit into
mainfrom
claude/dashboard-harden

Conversation

@unohee

@unohee unohee commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

Why

Step 0 of the dashboard redesign workflow (design review 2026-10-19, 19/40). These are behaviour defects on the operator's highest-stakes controls, independent of any visual direction, so they ship first and separately.

What

  • Stop / Restart (dashboardHtml.ts): check res.ok; say the outcome on the button (Stop failed + reason as title, or Restart sent) and in the live log.
  • Heartbeat: POST /api/heartbeat answers 503 when no runner is attached (openswarm dash), instead of a 202 nothing could follow up. The client waits at most 15 s for the SSE start signal, then shows No response with the reason.
  • Fleet-wide switches: provider buttons arm like Stop (Switch fleet?, one armed at a time). A Thinking change is staged behind a Set fleet to X? confirm that lapses after 6 s back to the applied level.
  • Chat recipient (chatView.mjs, conversationModel.mjs): the composer used to follow whoever spoke last. It is now a pinned To picker over every addressable agent+task. It defaults to the first addressable speaker and only the operator moves it. It warns, without blocking, when the pinned agent failed, expired or already delivered its result.
  • /api/service/* routes moved verbatim into src/support/webServiceControl.ts so web.ts stays under the 1500-line gate. It is coverage-excluded like webExecTasks.ts, for the same reason.

Verification

  • tests/web/supervisorActions.test.ts (new) runs the real inline Supervisor script in jsdom with scripted fetch and a hand-driven clock: 9 tests.
  • tests/web/chatView.test.ts: 4 new recipient-pin tests.
  • src/support/web.heartbeat.test.ts: 503 without a runner. The existing web.serviceControl.test.ts still passes against the moved routes.
  • Reverting the source changes turns 12 of the new tests red; restoring makes them green.
  • npx vitest run tests/web src/support all green. Lint shows no new warnings. Typecheck and build pass.
  • Browser check against openswarm dash from this build (1440 dark, 390 light): Heartbeat shows Heartbeat failed with the 503 reason; provider shows Switch fleet?; Thinking shows Set fleet to Low?; Chat shows the To: CopperBuilds · worker · AX-1767 picker with the failed warning.

The control bar still wraps when the Thinking confirm appears. Step 6 of the redesign replaces that bar.

…at recipient

The dashboard design review (2026-10-19) found four trust failures on the
operator's highest-stakes controls:

- Stop/Restart ignored res.ok, so a refused systemctl call was logged as
  "requested". The button now says "Stop failed"/"Restart sent" with the
  daemon's reason as its title, and the live log records the failure.
- Heartbeat could spin on "Running…" forever: the route answered 202 even
  with no runner attached (`openswarm dash`), and the start signal is an SSE
  event that a skipped or dropped run never sends. The route now answers 503
  without a runner, and the button gives up after 15s with "No response".
- Provider and Thinking switched the whole fleet on one click. The provider
  button now arms like Stop ("Switch fleet?"), and a Thinking change is
  staged behind a "Set fleet to X?" confirm that lapses after 6s.
- The chat composer re-targeted whoever spoke last, so a message drafted for
  one agent could leave addressed to another. The recipient is now a pinned
  picker that only the operator moves, and it warns (without refusing) when
  the pinned agent has failed, expired or delivered its result.

The /api/service/* routes move verbatim into webServiceControl.ts so
web.ts stays under the 1500-line gate.
@unohee
unohee merged commit bf435cb into main Oct 19, 2026
7 checks passed
@unohee
unohee deleted the claude/dashboard-harden branch October 19, 2026 03:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant